package net.kunyv.DAL;

import net.kunyv.entity.DaoEntity;
import net.kunyv.entity.DbConfig;
import net.kunyv.entity.EntityColumn;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class MySqlInitBeanImpl
        implements InitBean {
    public List<EntityColumn> init(DbConfig dbconfig, DaoEntity de) throws Exception {
        this.dbconfig = dbconfig;
        Connection conn = null;
        List<EntityColumn> list = new ArrayList<>();
        String strsql = null;

        if (de.isCustomSql()) {
            strsql = de.getSql();
        } else {
            String url = dbconfig.getUrl();
            int endindex = url.indexOf("?");
            int begindex = url.lastIndexOf("/");
            String schema = url.substring(begindex + 1, endindex);


            strsql = "select column_name,is_nullable,data_type,character_maximum_length,numeric_precision,numeric_scale,column_key,column_comment  from information_schema.columns  where table_name='" + de.getTableName().toLowerCase() + "' and table_schema='" + schema + "'";
        }

        String tablecomment = getTableComment(de);
        if (tablecomment != null) {
            de.setTableComment(tablecomment);
        } else {
            de.setTableComment("");
        }
        if (de.getEntityName() != null);


        ResultSet rs = null;

        try {
            conn = DbSession.getConnection(dbconfig);
            if (de.isCustomSql()) {
                HashMap<String, String> commentmap = getComments(de);
                PreparedStatement pstmt = conn.prepareStatement(strsql);
                pstmt.execute();
                ResultSetMetaData rsmd = pstmt.getMetaData();
                int size = rsmd.getColumnCount();


                for (int i = 0; i < size; i++) {
                    EntityColumn ec = new EntityColumn();
                    String columnName = rsmd.getColumnName(i + 1);
                    String columnTypName = rsmd.getColumnTypeName(i + 1);
                    if (rsmd.isNullable(i + 1) == 0) {
                        ec.setRequired(true);
                    }
                    ec.setMybatis(de.isMybatis());
                    ec.setDatabaseName(de.getDatabaseName());

                    ec.setColumnNam(columnName);

                    if (rsmd.getPrecision(i + 1) == 0) {
                        if (!columnTypName.equalsIgnoreCase("DATE") && !columnTypName.equalsIgnoreCase("DATETIME")) {
                            ec.setColumnTyp("DECIMAL");
                        } else {
                            ec.setColumnTyp(columnTypName);
                        }
                    } else {
                        ec.setColumnTyp(columnTypName);
                    }
                    ec.setEntityColumnComment(commentmap.get(ec.getColumnNam().toUpperCase()));
                    ec.setPrecision(rsmd.getPrecision(i + 1));
                    ec.setScale(rsmd.getScale(i + 1));
                    list.add(ec);
                }
            } else {

                PreparedStatement pstmt = conn.prepareStatement(strsql);
                rs = pstmt.executeQuery();
                while (rs.next()) {
                    EntityColumn ec = new EntityColumn();
                    String columnName = rs.getString("column_name");
                    String columnTypName = rs.getString("data_type");
                    String key = rs.getString("column_key");
                    if (rs.getString("column_key") != null && !rs.getString("column_key").equals("")) {
                        ec.setKey(true);
                    } else {
                        ec.setKey(false);
                    }
                    ec.setMybatis(de.isMybatis());
                    ec.setColumnNam(columnName);
                    ec.setDatabaseName(de.getDatabaseName());
                    ec.setColumnTyp(columnTypName);
                    if (rs.getObject("numeric_precision") != null) {
                        ec.setPrecision(Integer.parseInt(rs.getObject("numeric_precision").toString()));
                    } else {
                        ec.setPrecision(rs.getInt("character_maximum_length"));
                    }
                    if (rs.getObject("numeric_scale") != null) {
                        ec.setPrecision(Integer.parseInt(rs.getObject("numeric_precision").toString()));
                    }
                    ec.setEntityColumnComment(rs.getString("column_comment"));
                    if (rs.getString("is_nullable").equals("NO")) {
                        ec.setRequired(true);
                    }
                    list.add(ec);
                }

            }
        } catch (SQLException e) {
            e.printStackTrace();
            throw new Exception(e);
        } finally {
            DbSession.closeConnection(conn);
        }
        return list;
    }



    private DbConfig dbconfig;



    private HashMap<String, String> getComments(DaoEntity de) {
        HashMap<String, String> map = new HashMap<>();
        Connection conn = DbSession.getConnection(this.dbconfig);
        String url = this.dbconfig.getUrl();
        int endindex = url.indexOf("?");
        int begindex = url.lastIndexOf("/");
        String schema = url.substring(begindex + 1, endindex);
        String strsql = "select column_name,is_nullable,data_type,character_maximum_length,numeric_precision,numeric_scale,column_key,column_comment  from information_schema.columns  where table_schema='" + schema + "'";

        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            pstmt = conn.prepareStatement(strsql);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                if (null == rs.getString(8) || "".equals(rs.getString(8))) {
                    map.put(rs.getString(1).toUpperCase(), rs.getString(8));
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {

                    e.printStackTrace();
                }
            }
            if (pstmt != null) {
                try {
                    pstmt.close();
                } catch (SQLException e) {

                    e.printStackTrace();
                }
            }
            DbSession.closeConnection(conn);
        }

        return map;
    }

    private String getTableComment(DaoEntity de) {
        String tablecomment = "";
        Connection conn = DbSession.getConnection(this.dbconfig);

        String sql = "select table_comment from information_schema.tables where  table_type='base table' and table_name='" + de.getTableName().toLowerCase() + "'";
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();

            if (rs.isAfterLast() == rs.isBeforeFirst()) {
                return null;
            }
            while (rs.next()) {
                String s = rs.getString(1);
                if (!"".equals(s)) {
                    tablecomment = s;
                }
            }

        }
        catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {

                    e.printStackTrace();
                }
            }
            if (pstmt != null) {
                try {
                    pstmt.close();
                } catch (SQLException e) {

                    e.printStackTrace();
                }
            }
            DbSession.closeConnection(conn);
        }

        return tablecomment;
    }
}
